<?php
class BMSC_Privilege extends BMSC_Db
{	
	public function getPagePrivileges($memberID)
	{
		try
		{
			$query = "CALL sp_admin_get_page_privileges(?)";
			$stmt = $this->_readerDb->query($query, array($memberID));
			return $result = $stmt->fetchAll();
		} catch (Exception $e) {
			throw $e;
		}		
	}

	public function getPrivilege($memberID, $module)
	{
		try
		{
			$query = "CALL sp_admin_get_privilege(?, ?)";
			$stmt = $this->_readerDb->query($query, array($memberID, $module));
			return $result = $stmt->fetchAll();
		}
		catch (Exception $ex)
		{
			throw $ex;
		}
	}
	
	public function getPageList()
	{
		try
		{
			$query = "CALL sp_admin_get_page_list()";
			$stmt = $this->_readerDb->query($query);
			return $result = $stmt->fetchAll();
		} catch (Exception $e) {
			throw $e;
		}
	}
	
	public function updatePrivileges($memberID, $module, $selectPriv, $insertPriv, $updatePriv, $deletePriv)
	{
		// file_put_contents(APPLICATION_PATH . '/../www/debug.txt', $r);
		try {			
			// get privilege row if it exists
			$privRow = $this->_checkPrivilegeRow($memberID, $module);
		
			// remove privilege row if it already exists and all privileges are not one
			if(!empty($privRow) && $selectPriv != 1 && $insertPriv != 1 && $updatePriv != 1 && $deletePriv != 1) {
				return $this->_deletePrivilegeRow($memberID, $module);				
			}
					
			// insert privilege row if it doesn't exist and one of privs is one
			if(empty($privRow) && ($selectPriv == 1 || $insertPriv == 1 || $updatePriv == 1 || $deletePriv == 1)) { 
				return $this->_insertPrivilegeRow($memberID, $module, $selectPriv, $insertPriv, $updatePriv, $deletePriv);							
			}
			
			// update privlege row if it already exists and one of privs is one
			if(!empty($privRow) && ($selectPriv == 1 || $insertPriv == 1 || $updatePriv == 1 || $deletePriv == 1)) {
				return $this->_updatePrivilegeRow($memberID, $module, $selectPriv, $insertPriv, $updatePriv, $deletePriv);
			}
		} catch (Exception $e) {
			throw $e;
		}
	}
	
	/**
	$oldPrivs and $newPrivs has form: 
	Array(
		1 => Array('s' => 1, 'u' => 1),
		3 => Array('d' => 1)
	)
	with: 1 and 3 are pageIDs. 's', 'u', 'd' are select, update, delete respectively.	
	**/
	public function updatePagePrivileges($memberID, $oldPrivs, $newPrivs)
	{
		try {			
			// sort them first
			$this->_sortPrivs($oldPrivs);
			$this->_sortPrivs($newPrivs);
			
			// find the privs needs to be inserted or updated
			$inserted = array();
			foreach($newPrivs as $npi => $np) {
				$diff = 1;
				foreach($oldPrivs as $opi => $op) {
					if($npi == $opi && $np == $op) { // if 'id' and 'privs' equal
						$diff = 0;
						break;
					}
				}
				if($diff) {
					$inserted[$npi] = $np;
				}
			}
			// find the privs needs to be deleted
			$deleted = array();
			foreach($oldPrivs as $opi => $op) {
				$diff = 1;
				foreach($newPrivs as $npi => $np) {
					if($opi == $npi) { // if 'id' is equal
						$diff = 0;
						break;
					}
				}
				if($diff) {
					$deleted[$opi] = $op;
				}
			}			
			
			$affectedRows = 0;
			foreach($inserted as $ii => $iz) {
				$privRow = $this->_checkPagePrivilegeRow($memberID, $ii);
				if(empty($privRow)) {
					$r = $this->_insertPagePrivilegeRow($memberID, 
													    $ii, 
													    isset($iz['s']) ? 1 : 0,
													    isset($iz['u']) ? 1 : 0,
													    isset($iz['d']) ? 1 : 0);
					$affectedRows += $r;
				} else {
					$r = $this->_updatePagePrivilegeRow($memberID,
														$ii,
														isset($iz['s']) ? 1 : 0,
													    isset($iz['u']) ? 1 : 0,
													    isset($iz['d']) ? 1 : 0);
					$affectedRows += $r;					
				}
			}
			
			foreach($deleted as $di => $dz) {
				$privRow = $this->_checkPagePrivilegeRow($memberID, $di);
				if(!empty($privRow)) {
					$r = $this->_deletePagePrivilegeRow($memberID, $di);
					$affectedRows += $r;
				} else {
					return -1; // error report
				}
			}
			return $affectedRows;
		} catch (Exception $e) {
			throw $e;
		}	
	}
	
	
	////////////////// Helpers //////////////////////
	private function _insertPagePrivilegeRow($memberID, $pageID, $selectPriv, $updatePriv, $deletePriv)
	{
		$data = array();
		$data['MEMBER_ID'] = $memberID;
		$data['CONTENT_ID'] = $pageID;
		$data['MODULE'] = 'page';
		$data['SELECT_PRIV'] = $selectPriv;
		$data['UPDATE_PRIV'] = $updatePriv;
		$data['DELETE_PRIV'] = $deletePriv;
		return $this->_writerDb->insert('privilege', $data);	
	}
	
	private function _updatePagePrivilegeRow($memberID, $pageID, $selectPriv, $updatePriv, $deletePriv)
	{
		$data = array();
		$data['SELECT_PRIV'] = $selectPriv;
		$data['UPDATE_PRIV'] = $updatePriv;
		$data['DELETE_PRIV'] = $deletePriv;
		
		$where = array();
		$where['MEMBER_ID = ?'] = $memberID;
		$where['CONTENT_ID = ?'] = $pageID;
		$where['MODULE = ?'] = 'page';
		return $this->_writerDb->update('privilege', $data, $where);
	}
	
	private function _deletePagePrivilegeRow($memberID, $pageID)
	{
		$where = array();
		$where['MEMBER_ID = ?'] = $memberID;
		$where['CONTENT_ID = ?'] = $pageID;
		$where['MODULE = ?'] = 'page';
		return $this->_writerDb->delete('privilege', $where);	
	}
	
	private function _sortPrivs($privs)
	{
		asort($privs);
		foreach($privs as $p) {
			asort($p);
		}
	}
	
	private function _checkPagePrivilegeRow($memberID, $pageID)
	{
		$select = $this->_readerDb->select()->from('privilege')->where('MEMBER_ID = ? AND MODULE = \'page\' AND CONTENT_ID = ?');
		$r = $this->_readerDb->fetchRow($select, array($memberID, $pageID));	
		return $r;
	}
	
	
	
	private function _checkPrivilegeRow($memberID, $module)
	{
		$select = $this->_readerDb->select()->from('privilege')->where('MEMBER_ID = ? AND MODULE = ?');
		$r = $this->_readerDb->fetchRow($select, array($memberID, $module));	
		return $r;
	}
	
	private function _deletePrivilegeRow($memberID, $module)
	{
		$where = array();
		$where['MODULE = ?'] = $module;
		$where['MEMBER_ID = ?'] = $memberID;
		return $this->_writerDb->delete('privilege', $where);
	}
	
	private function _insertPrivilegeRow($memberID, $module, $selectPriv, $insertPriv, $updatePriv, $deletePriv)
	{
		$privInfo = array();			
		$privInfo['SELECT_PRIV'] = $selectPriv;
		$privInfo['INSERT_PRIV'] = $insertPriv;
		$privInfo['UPDATE_PRIV'] = $updatePriv;
		$privInfo['DELETE_PRIV'] = $deletePriv;
		$privInfo['MEMBER_ID'] = $memberID;
		$privInfo['MODULE'] = $module;
		return $this->_writerDb->insert('privilege', $privInfo);
	}
	
	private function _updatePrivilegeRow($memberID, $module, $selectPriv, $insertPriv, $updatePriv, $deletePriv)
	{
		$privInfo = array();			
		$privInfo['SELECT_PRIV'] = $selectPriv;
		$privInfo['INSERT_PRIV'] = $insertPriv;
		$privInfo['UPDATE_PRIV'] = $updatePriv;
		$privInfo['DELETE_PRIV'] = $deletePriv;		
		$where = array();
		$where['MEMBER_ID = ?'] = $memberID;
		$where['MODULE = ?'] = $module;		
		return $this->_writerDb->update('privilege', $privInfo, $where);
	}
}
?>